<?php
class Curl{
	private static $_model = null;
	
	// 访问IP
	private $_ip = null;
	
	// 浏览器信息
	private $_userAgent = null;
	
	// cookie 文件名称
	private $_cookieFile = null;
	
	// curl handle
	protected $ch = '';
	
	// curl 参数
	protected $params = array(
		'data'=> array(),
		'is_post'=> false,
		'use_cookie'=> false,
		'referer'=>'http://www.google.com',
		'https' => false,
		'ssl_verifypeer'=> true,
		'header'=> false,
		'transfer'=> true,
		'timeout'=> 10,
		'http_header'=> array(
			'Connection:keep-alive',
			'Accept-Language:zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4',
			'X-Requested-With:XMLHttpRequest',
			'Content-Type:application/x-www-form-urlencoded; charset=UTF-8',
		)
	);
	
	// 单例模式
	public static function model($className = __CLASS__) {
		null === self::$_model && self::$_model = new $className;
		
		return self::$_model;
	}
	
	public function __set($name, $value) {
		$setter = 'set'.ucfirst($name);
		if(method_exists($this, $setter)) return $this->$setter($value);
		
		return isset($this->params[$name]) ? $this->params[$name] = $value : '';
	}
	
	public function __get($name) {
		$getter = 'get'.ucfirst($name);
		if(method_exists($this, $getter)) return $this->$getter();
		
		return isset($this->params[$name]) ? $this->params[$name] : '';
	}
	
	// 请求
	public function request($url, $params = array()) {
		$params = array_merge($this->params, $params);
		$ip = $this->createIp();
		
		$this->ch = curl_init($url);
		$this->setOption(CURLOPT_TIMEOUT, $params['timeout']);
		$this->setOption(CURLOPT_REFERER, $params['referer']);
		$this->setOption(CURLOPT_HEADER, $params['header']);
		$this->setOption(CURLOPT_RETURNTRANSFER, $params['transfer']);
		$this->setOption(CURLOPT_USERAGENT, $this->createAgent());

		$this->setOption(CURLOPT_HTTPHEADER, array_merge(
			$params['http_header'],
			array(
				'X-FORWARDED-FOR:'.$ip,
				'CLIENT-IP:'.$ip,
			)
		));

		if(true == $params['use_cookie']) {
			$this->setOption(CURLOPT_COOKIEFILE, $this->createCookie());
			$this->setOption(CURLOPT_COOKIEJAR, $this->createCookie());
		}
		
		if(true == $params['https']) {
			// 模拟证书地址： http://curl.haxx.se/ca/cacert.pem
			$this->setOption(CURLOPT_SSL_VERIFYPEER, $params['ssl_verifypeer']);
			$this->setOption(CURLOPT_SSL_VERIFYHOST, TRUE);
			$this->setOption(CURLOPT_CAINFO, DIR.'/source/cacert.pem');
		}

		if(true == $params['is_post']) {
			$data = is_array($params['data']) ? http_build_query($params['data']) : $params['data'];
			$this->setOption(CURLOPT_POST, TRUE);
			$this->setOption(CURLOPT_POSTFIELDS, $data);
		} else {
			$this->setOption(CURLOPT_HTTPGET, TRUE);
		}

		$contents = curl_exec($this->ch);
		curl_close($this->ch);
		return $contents;
	}
	
	// 设置curl参数
	public function setOption($key, $value) {
		curl_setopt($this->ch, $key, $value);
	}
	
	// 模拟访问IP
	public function createIp() {
		if(null === $this->ip) {
			$this->_ip = rand(10,255).'.'.rand(10,255).'.'.rand(10,255).'.'.rand(10,255);
		}
		return $this->_ip;
	}
	
	// 模拟 浏览器信息
	public function createAgent($refresh = false) {
		if(null == $this->_agent) {
			switch(rand(0,2)) {
				case 0: $agent = 'Mozilla/'.rand(4,5).'.0 (compatible; MSIE '.rand(6,10).'.0; Windows NT '.rand(5,6).'.2; .NET CLR 1.1.'.rand(11,55).'22)'; break;
				case 1: $agent = 'Mozilla/'.rand(4,5).'.0 (Windows NT '.rand(5,6).'.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/'.rand(15,28).'.0.912.'.rand(50,66).' Safari/535.7';break;
				case 2: $agent = 'Mozilla/'.rand(4,5).'.0 (X11; U; Linux i686; en-US; rv:1.'.rand(3,9).'.5) Gecko/'.rand(2004,2012).''.rand(10,12).''.rand(10,28).' Firefox/'.rand(1,7).'.0';break;
			}
			
			$this->_agent = $agent;
		}

		return $this->_agent;
	}
	
	// 创建 cookie 临时文件
	public function createCookie() {
		null === $this->_cookieFile && $this->cookie = tempnam($this->cookieDir, 'cookie');
		return $this->_cookieFile;
	}
	
	// 设置 cookie 文件
	public function setCookie($cookie) {
		$cookie = $this->cookieDir.'/'.$cookie;
		if(!file_exists($cookie)) file_put_contents($cookie, '');
		
		return $this->_cookieFile = $cookie;
	}
	
	// 获取 Cookie 存放目录
	public function getCookieDir() {
		$dir = DIR.'/cookie';
		if(!file_exists($dir)) mkdir($dir, 0755, true);
		
		return $dir;
	}
}
?>